Skip to content

02 有容乃大 - 内存容量与 free

free 显示系统内存使用量情况

  • free 指令用于显示当前系统内存使用情况,包含物理内存和交换内存的总量、使用量、空闲量情况。
  • 其数据取自 /proc/meminfo 文件。/proc/meminfo 文件包含了系统内存的详细信息。
  • 直接在终端输入 free 即可使用。
  • 在 Linux 系统中,为了提高磁盘 I/O 的效率,系统会使用一部分内存作为缓存(cache)和缓冲(buffer)。当这些缓存的数据不再需要时,它们可以被快速回收并用于其他用途。

free 指令指标含义

  • total:总内存。
  • used:已用内存。
  • free:空闲内存。
  • shared:共享内存(通常用于 tmpfs)。
  • buff/cache:缓冲区和缓存使用的内存。
  • available:可用内存,表示可以立即分配给新的进程而不会导致交换,不包括缓存和缓冲区。
bash
  ~ free
               total        used        free      shared  buff/cache   available
Mem:         3746560      715676      579456       10292     2833060     3030884
Swap:              0           0           0
  ~ cat -n /proc/meminfo
     1  MemTotal:        3746560 kB
     2  MemFree:          577188 kB
     3  MemAvailable:    3028684 kB
     4  Buffers:           97112 kB
     5  Cached:          2506520 kB
  • Mem 表示物理内存的使用情况。
    • total: 物理内存总量为 3746560 kB。
    • used: 物理内存已使用 715676 kB。
    • free: 物理内存空闲 579456 kB。
    • shared: 共享内存 10292 kB。
    • buff/cache: 被 buffer 和 cache 占用的内存 2833060 kB。
    • available: 可用内存 3030884 kB。
  • Swap 表示交换空间的使用情况(这里系统没有配置交换空间)。

free 与 avaliable 的区别

  • avaliable 值一般情况下会大于 free,小于 free + buffer/cache
  • 内核会将部分空闲内存用于缓存,以提高文件系统和磁盘 I/O 的性能
  • avaliable 在计算时包含了可回收的缓存
  • 并不是所有的 buffer/cache 内容均可被回收
  • avaliable 值是一个估算值,并不完全准确
  • 执行 echo 3 > /proc/sys/vm/drop_caches 会触发内存回收

  1. free:
    • free 表示当前未被使用的内存量,即完全没有被分配的内存。
    • 这部分内存处于空闲状态,没有被任何进程、缓冲区或缓存占用。可以直接用来分配给新的应用程序或进程。
    • free 内存不包括被缓存(cache)和缓冲(buffer)占用的内存。
  2. available:
    • available 是内核认为在满足当前所有缓存和缓冲需求后,还可以被分配给新应用程序的内存量。
    • 它计算的是 free 内存加上可以被回收的 bufferscache 内存,内核可以很容易地回收这些缓存以满足内存需求。
    • available 内存提供了一个更加真实的内存可用量,因为它考虑到了内存管理器回收缓存和缓冲的能力。

简而言之,free 是当前未被使用的内存,而 available 是考虑了内存回收机制后,实际上可以用的内存总量。在评估一个系统是否还有足够的内存来启动新的应用程序时,available 是一个更好的指标。

内存回收

内核会将一部分内存用于缓存磁盘数据和其他文件操作,以提高系统性能。这些缓存内存虽然已被使用,但可以在需要时回收以分配给应用程序。因此,available 内存更能准确地反映出系统在运行过程中可用的内存资源。

缓存内存

缓冲区和缓存内存(buff/cache)可以随时被回收用于新进程或当前进程。虽然这些内存被标记为已用(在 used 列中计算),但它们并未真正被锁定,可以立即释放。

重要性

  • free 列主要用来表示当前系统中完全空闲的内存量,但不能反映出真实的内存可用性。
  • available 列提供了更准确的系统可用内存量,是评估系统内存压力和决定是否需要增加内存或优化内存使用的更好指标。

常用参数

命令描述
-b (bytes)以字节为单位显示内存使用情况。
-k (kibibytes, KiB)以千字节为单位显示内存使用情况。
-m (mebibytes, MiB)以兆字节为单位显示内存使用情况。
-g (gibibytes, GiB)以吉字节为单位显示内存使用情况。
-h (human-readable)以人类可读的格式显示内存使用情况。
-l (low-mem details)显示低内存和高内存统计数据。
-o (omit buffers/cache)不显示缓冲区和缓存使用情况。
-s (seconds)持续显示内存使用情况,每隔几秒刷新一次。
-c (count)持续显示内存使用情况,刷新次数。
-t (total)显示内存使用总和。
-V (version)显示 free 命令的版本信息。

常用命令

命令描述
free -m显示内存使用情况,单位为 MB(兆字节)。
free -t显示内存的总量、已使用量、空闲量,并在最后添加一行显示所有内存(包括交换空间)的总和。
free -s 5 -c 3每隔 5 秒更新一次内存使用情况,总共更新 3 次后退出。
free -hs 10以人类可读的格式(如 KB、MB、GB)显示内存使用情况,并高亮显示超过 10% 使用的内存区域。

Swap 交换分区

Linux 的 Swap 交换分区是硬盘上的一块空间,它被用作虚拟内存,即当物理内存(RAM)不足时,操作系统可以将不常用的数据从物理内存移动到 Swap 分区,从而为更活跃的进程腾出空间。Swap 交换分区对于确保系统的稳定运行至关重要,尤其是在内存资源紧张的情况下。

  • 本质上是磁盘上的一个空间;
  • 类似于 Windows 的虚拟内存;
  • 用于解决内存容量不足的问题;
  • 当内存不足的时候,把该部分内容虚拟成内存;
  • 当 Swap 被使用时,往往意味着程序性能下降;
  • 通过 swapoff -a 指令可以关闭 Swap 分区,其中内容回写至内存中;

Swap 的作用

  1. 内存扩展:当系统的物理内存不足时,Swap 可以作为一种内存扩展手段,允许系统处理比物理内存更大的工作负载。
  2. 内存管理:操作系统使用 Swap 来管理内存,将不常用的内存页换出(swap out)到硬盘上,将常用的内存页保留在 RAM 中。
  3. 提高多任务处理能力:Swap 允许系统运行更多的进程,即使物理内存不足以容纳所有进程。
  4. 系统稳定性:当内存不足时,如果没有 Swap,系统可能会出现内存溢出错误,导致进程崩溃。Swap 可以作为缓冲,避免这种情况。

Swap 的类型

  1. 交换分区(Swap Partition):在硬盘上划分一块区域专门用作 Swap。
  2. 交换文件(Swap File):在文件系统中创建一个普通文件,可以动态创建和删除,将其作为 Swap 使用。

Swap 的配置

查看当前 Swap 使用情况

使用 free 命令查看当前 Swap 的使用情况:

bash
  ~ free -h
               total        used        free      shared  buff/cache   available
Mem:         3746560      715676      579456       10292     2833060     3030884
Swap:        2097148       10240     2086908

查看 Swap 分区

使用 swapon 命令查看当前激活的 Swap 分区和文件:

bash
  ~ swapon --show
NAME      TYPE      SIZE   USED PRIO
/swapfile file      2G     10M   -2

添加 Swap 分区

步骤命令描述
创建 Swap 分区sudo fdisk /dev/sdX使用 fdisk 工具在指定的磁盘上创建一个新的分区,并将其类型设置为 Swap。
格式化 Swap 分区sudo mkswap /dev/sdXn将新创建的 Swap 分区格式化为 Swap 文件系统。
激活 Swap 分区sudo swapon /dev/sdXn启用格式化后的 Swap 分区,使其可用于系统交换空间。
永久添加到 fstab/dev/sdXn none swap sw 0 0/etc/fstab 文件中添加此行,以确保 Swap 分区在系统启动时自动挂载。

添加 Swap 文件

步骤命令描述
创建 Swap 文件sudo fallocate -l 2G /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
使用 fallocate 命令或 dd 命令创建一个大小为 2GB 的 Swap 文件。
设置正确的权限sudo chmod 600 /swapfile设置 Swap 文件的权限,以确保只有 root 用户可以访问。
格式化 Swap 文件sudo mkswap /swapfile将创建的 Swap 文件格式化为 Swap 分区。
激活 Swap 文件sudo swapon /swapfile启用格式化后的 Swap 文件,使其可用于系统交换空间。
永久添加到 fstab/swapfile none swap sw 0 0/etc/fstab 文件中添加此行,以确保 Swap 文件在系统启动时自动挂载。

移除 Swap 分区或文件

步骤命令描述
关闭 Swapsudo swapoff /dev/sdXn停用指定的 Swap 分区或文件,使其不再作为交换空间使用。
从 fstab 移除删除 /etc/fstab 文件中的 Swap 条目/etc/fstab 文件中找到并删除与 Swap 分区或文件相关的条目。
删除 Swap 文件sudo rm /swapfile如果是使用文件作为 Swap,则删除该 Swap 文件。

Swap 的调优

swappiness 参数

swappiness 是一个内核参数,控制系统使用 Swap 的倾向(系统使用 Swap 的积极性)。范围为 0 到 100,值越高,系统越倾向于使用 Swap。默认值通常在 60 左右。

  • 0:尽量避免使用 Swap,只有在物理内存耗尽时才使用。
  • 100:积极使用 Swap,尽早将内存页移动到 Swap 中。
步骤命令描述
查看当前 swappiness 值cat /proc/sys/vm/swappiness显示当前系统设置中的 swappiness 值,它决定了系统使用 Swap 空间的频率。
临时更改 swappiness 值sudo sysctl vm.swappiness=10立即更改 swappiness 值,但重启后失效。
永久更改 swappiness 值vm.swappiness = 10/etc/sysctl.conf 文件中添加此行,以确保每次系统启动时都会设置 swappiness 值。

调整 Swap 优先级

可以通过调整优先级来控制多个 Swap 分区或文件的使用顺序。优先级范围为 -1 到 32767,数值越高优先级越高。

激活 Swap 时指定优先级:

bash
sudo swapon --priority 100 /dev/sdXn

Swap 的应用

  • 大小建议:Swap 的大小通常建议为物理内存的 1 到 2 倍,但这也取决于具体的使用场景。对于拥有大量内存的服务器,Swap 的大小可以相对较小。
  • 监控:定期监控 Swap 的使用情况,如果 Swap 使用频繁,可能需要增加物理内存或优化系统配置。
  • 性能考虑:Swap 的性能远低于 RAM,因此应尽量避免过度依赖 Swap。
  • 禁用 Swap:对于一些特定的应用,如数据库,为了提高性能,可能会选择完全禁用 Swap。

OOM

  • OOM,英文全称为 Out Of Memory,OOM 事件是在系统内存耗尽时由操作系统启动的内存管理机制。

  • 指程序在运行过程中,申请内存空间时无法获得足够的内存而导致的错误。

  • 当内存资源不足情况下会出现如下几种情况:

    • 有 Swap 分区:使用了一部分 Swap,程序性能下降,系统继续运行;
    • 有 Swap 分区:使用了全部 Swap 空间后,发生 OOM;
    • 无 Swap 分区=>发生 OOM;
  • OOM 之后,内核会 kill 掉一些进程;

    • kill 用户态进程:业务错误,系统继续运行;
    • kill 内核进程:系统可能出现岩机;
  • 一般来说,系统会优先 kill 内存占用量大的进程。

  • 具体的策略,与系统版本、配置等有关。

什么是 OOM

OOM(Out of Memory)是指系统内存耗尽时,操作系统(OS)无法为进程分配所需的内存资源的情况。当这种情况发生时,Linux 内核的 OOM 杀手(OOM Killer)会启动,以终止一个或多个进程来释放内存,确保系统继续运行。

OOM Killer 的工作原理

当系统内存耗尽时,OOM Killer 会选择性地终止一些进程来释放内存资源。选择过程基于每个进程的 OOM 分数,该分数是通过以下几个因素计算得出的:

  1. 进程使用的内存量:使用内存越多,OOM 分数越高。
  2. 进程的优先级:低优先级进程更可能被终止。
  3. 进程的“oom_score_adj”值:通过调整该值,用户可以影响进程被终止的概率。

查看和调整 OOM 分数

查看进程的 OOM 分数

每个进程都有一个 oom_score 文件,可以通过查看 /proc 文件系统来访问。例如,要查看 PID 为 1234 的进程的 OOM 分数:

bash
cat /proc/1234/oom_score

调整进程的 OOM 分数

可以通过调整 oom_score_adj 文件来影响进程的 OOM 分数。范围是 -1000 到 1000,值越高,进程越容易被 OOM Killer 终止。值越低,进程越不容易被终止。例如,要将 PID 为 1234 的进程的 OOM 分数调整为 -500:

bash
echo -500 | sudo tee /proc/1234/oom_score_adj

处理 OOM 事件

当 OOM 事件发生时,系统会记录相关信息,可以通过查看系统日志来了解 OOM Killer 的行为。

查看 OOM 日志

系统日志通常位于 /var/log/syslog/var/log/messages 中,可以使用 grep 命令查找 OOM 相关的信息。

bash
grep -i 'killed process' /var/log/syslog

防止 OOM 的方法

  1. 增加物理内存:最直接的方法是增加物理内存。
  2. 添加或扩展 Swap 分区:通过增加 Swap 空间,可以在物理内存耗尽时提供额外的内存资源。
  3. 优化内存使用:通过优化应用程序,减少内存泄漏和不必要的内存使用。
  4. 设置进程的 OOM 分数:调整关键进程的 oom_score_adj 值,确保它们不会被 OOM Killer 终止。

应用

设置关键进程的 OOM 分数

假设有一个关键进程,其 PID 为 5678,不希望被 OOM Killer 终止,可以将其 oom_score_adj 值设置为 -1000:

bash
echo -1000 | sudo tee /proc/5678/oom_score_adj

监控内存使用

可以使用 tophtopfree 等命令实时监控系统内存使用情况,预防 OOM 事件的发生。

bash
top -o %MEM